package com.example.native_view

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.LinearGradient
import android.graphics.Paint
import android.graphics.Shader
import android.os.Handler
import android.os.Looper
import android.view.Surface
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.embedding.engine.plugins.activity.ActivityAware
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
import io.flutter.view.TextureRegistry
import java.util.concurrent.atomic.AtomicBoolean

/** NativeViewPlugin */
class NativeViewPlugin :
    ActivityAware,
    FlutterPlugin,
    MethodCallHandler {
    // The MethodChannel that will the communication between Flutter and native Android
    //
    // This local reference serves to register the plugin with the Flutter Engine and unregister it
    // when the Flutter Engine is detached from the Activity
    private lateinit var channel: MethodChannel
    private lateinit var textureRegistry: TextureRegistry

    override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
        textureRegistry=  flutterPluginBinding.textureRegistry
        channel = MethodChannel(flutterPluginBinding.binaryMessenger, "native_view")
        channel.setMethodCallHandler(this)
    }

    override fun onMethodCall(
        call: MethodCall,
        result: Result
    ) {
        when (call.method) {
            "getPlatformVersion" -> {
                result.success("1.0.1")
            }
            "createSurfaceTextureDemo" -> {
                createSurfaceTextureDemo(result)
            }
            "createSurfaceProducerDemo" -> {
                createSurfaceProducerDemo(result)
            }
            "createManualSurfaceTextureDemo" -> {
                createManualSurfaceTextureDemo(result)
            }
            "disposeTexture" -> {
                val textureId = call.argument<Int>("textureId")
                textureId?.let { disposeTexture(it, result) } ?: result.error(
                    "INVALID_ARGUMENT",
                    "Texture ID is required",
                    null
                )
            }
            else -> result.notImplemented()
        }
    }

    override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
        channel.setMethodCallHandler(null)
    }

    private val activeRenderers = mutableMapOf<Int, TextureRenderer>()
    // 方法1: 使用 textureRegistry.createSurfaceTexture() - 标准方式
    private fun createSurfaceTextureDemo(result: Result) {
        try {
            val textureEntry = textureRegistry.createSurfaceTexture()
            val renderer = TextureRenderer(mContext!!, textureEntry, RenderType.COLOR_GRADIENT)
            renderer.start()

            activeRenderers[textureEntry.id().toInt()] = renderer
            result.success(textureEntry.id())
        } catch (e: Exception) {
            result.error("CREATE_ERROR", "Failed to create surface texture: ${e.message}", null)
        }
    }

    // 方法2: 使用 textureRegistry.createSurfaceProducer() - 底层方式
    private fun createSurfaceProducerDemo(result: Result) {
        try {
            // 注意：createSurfaceProducer() 在较新的Flutter版本中可能已变更
            // 这里使用反射或其他可用API来访问
            val textureEntry = textureRegistry.createSurfaceTexture()
            textureRegistry.createSurfaceProducer().setCallback()
            val renderer = TextureRenderer(mContext!!, textureEntry, RenderType.ROTATING_RECT)
            renderer.start()

            activeRenderers[textureEntry.id().toInt()] = renderer
            result.success(textureEntry.id())
        } catch (e: Exception) {
            result.error("CREATE_ERROR", "Failed to create surface producer: ${e.message}", null)
        }
    }

    // 方法3: 使用手动创建的 SurfaceTexture - 自定义方式
    private fun createManualSurfaceTextureDemo(result: Result) {
        try {
            // 创建新的SurfaceTexture
            val surfaceTexture = android.graphics.SurfaceTexture(0).apply {
                setDefaultBufferSize(300, 200)
            }

            // 注册到Flutter纹理系统
            val textureEntry = textureRegistry.registerSurfaceTexture(surfaceTexture)

            val renderer = TextureRenderer(mContext!!, textureEntry, RenderType.ANIMATED_CIRCLE)
            renderer.start()

            activeRenderers[textureEntry.id().toInt()] = renderer
            result.success(textureEntry.id())
        } catch (e: Exception) {
            result.error("CREATE_ERROR", "Failed to create manual surface texture: ${e.message}", null)
        }
    }

    private fun disposeTexture(textureId: Int, result: Result) {
        activeRenderers[textureId]?.let { renderer ->
            renderer.stop()
            renderer.dispose()
            activeRenderers.remove(textureId)
            result.success(null)
        } ?: result.error("NOT_FOUND", "Texture with ID $textureId not found", null)
    }

    fun dispose() {
        activeRenderers.values.forEach { it.dispose() }
        activeRenderers.clear()
    }
    private var mContext: Context?=null;

    override fun onAttachedToActivity(binding: ActivityPluginBinding) {
        mContext=binding.activity;
    }

    override fun onDetachedFromActivityForConfigChanges() {

    }

    override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {

    }

    override fun onDetachedFromActivity() {
        mContext=null
    }
}

// 渲染类型枚举
enum class RenderType {
    COLOR_GRADIENT,    // 颜色渐变
    ROTATING_RECT,      // 旋转矩形
    ANIMATED_CIRCLE     // 动画圆圈
}

// 纹理渲染器
class TextureRenderer(
    private val context: Context,
    private val textureEntry: TextureRegistry.SurfaceTextureEntry,
    private val renderType: RenderType
) {
    private val surface: Surface = Surface(textureEntry.surfaceTexture())
    private val handler = Handler(Looper.getMainLooper())
    private val isRunning = AtomicBoolean(false)

    private var animationProgress = 0f
    private var rotationAngle = 0f
    private var circleSize = 0f

    private val paint = Paint().apply {
        isAntiAlias = true
        style = Paint.Style.FILL
    }

    private val drawRunnable = object : Runnable {
        override fun run() {
            if (!isRunning.get()) return

            val canvas: Canvas? = surface.lockCanvas(null)
            canvas?.let { drawToCanvas(it) }

            animationProgress += 0.02f
            if (animationProgress >= 1f) animationProgress = 0f

            rotationAngle += 3f
            if (rotationAngle >= 360f) rotationAngle = 0f

            circleSize = 50f + 30f * sin(animationProgress * 2 * Math.PI).toFloat()

            if (isRunning.get()) {
                handler.postDelayed(this, 16) // ~60fps
            }
        }
    }

    private fun drawToCanvas(canvas: Canvas) {
        when (renderType) {
            RenderType.COLOR_GRADIENT -> drawColorGradient(canvas)
            RenderType.ROTATING_RECT -> drawRotatingRect(canvas)
            RenderType.ANIMATED_CIRCLE -> drawAnimatedCircle(canvas)
        }

        surface.unlockCanvasAndPost(canvas)
    }

    private fun drawColorGradient(canvas: Canvas) {
        val colors = intArrayOf(
            Color.HSVToColor(floatArrayOf(animationProgress * 360f, 1f, 1f)),
            Color.HSVToColor(floatArrayOf((animationProgress * 360f + 180f) % 360f, 1f, 1f))
        )

        val gradient = LinearGradient(
            0f, 0f, canvas.width.toFloat(), canvas.height.toFloat(),
            colors, null, Shader.TileMode.CLAMP
        )

        paint.shader = gradient
        canvas.drawRect(0f, 0f, canvas.width.toFloat(), canvas.height.toFloat(), paint)
        paint.shader = null

        // 添加文字标识
        drawText(canvas, "SurfaceTexture")
    }

    private fun drawRotatingRect(canvas: Canvas) {
        canvas.drawColor(Color.WHITE)

        paint.color = Color.BLUE
        val centerX = canvas.width / 2f
        val centerY = canvas.height / 2f

        canvas.save()
        canvas.rotate(rotationAngle, centerX, centerY)
        canvas.drawRect(
            centerX - 40f, centerY - 40f,
            centerX + 40f, centerY + 40f,
            paint
        )
        canvas.restore()

        drawText(canvas, "SurfaceProducer")
    }

    private fun drawAnimatedCircle(canvas: Canvas) {
        canvas.drawColor(Color.BLACK)

        paint.color = Color.GREEN
        val centerX = canvas.width / 2f
        val centerY = canvas.height / 2f

        canvas.drawCircle(centerX, centerY, circleSize, paint)

        drawText(canvas, "Manual ST", Color.WHITE)
    }

    private fun drawText(canvas: Canvas, text: String, mColor: Int = Color.BLACK) {
        val textPaint = Paint().apply {
            color = mColor
            textSize = 20f
            textAlign = Paint.Align.CENTER
        }

        canvas.drawText(text, canvas.width / 2f, 30f, textPaint)
    }

    fun start() {
        if (isRunning.compareAndSet(false, true)) {
            textureEntry.surfaceTexture().setDefaultBufferSize(300, 200)
            handler.post(drawRunnable)
        }
    }

    fun stop() {
        isRunning.set(false)
        handler.removeCallbacks(drawRunnable)
    }

    fun dispose() {
        stop()
        surface.release()
        textureEntry.release()
    }

    private fun sin(value: Double): Double = kotlin.math.sin(value)
}
